/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package simplerecipes;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;
import simplerecipes.model.Ingredient;
import simplerecipes.model.MeasurementType;
import simplerecipes.model.Recipe;
import simplerecipes.model.Unit;

/**
 *
 * @author matamh0a
 */
public class IngredientTableModel extends AbstractTableModel implements 
        PropertyChangeListener{
    
    public static final String[] COLUMN = {
        "Include", "Quantity", "Unit", "%", "Weight", "Ingredient", "/Unit", "Calories/Unit",
        "Calories", "Calories(%)", "Calories/Serving", "Cost"
    };
    
    Recipe recipe;
    ArrayList<Ingredient> ingredients;

    public IngredientTableModel(Recipe recipe, ArrayList<Ingredient> ingredients) {
        this.recipe = recipe;
        this.ingredients = ingredients;
        
        COLUMN[4] += "(" + recipe.getUnit()  + ")";
        COLUMN[6] = recipe.getUnit() + COLUMN[6];
        
        
        recipe.addPropertyChangeListener(this);
    }
    
    public int getRowCount() {
        return recipe.getIngredients().size();
    }

    public int getColumnCount() {
        return COLUMN.length;
    }

    @Override
    public String getColumnName(int column) {
        return COLUMN[column];
    }
    
    public Object getValueAt(int rowIndex, int columnIndex) {
        return new MesuredIngredientAdaptor(recipe.getIngredients().
                get(rowIndex), recipe).getValueAt(columnIndex, recipe.getUnit());
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        //System.out.println("aValue --> " + aValue.toString());
        switch (columnIndex) {
            case 0: // Included
                recipe.getIngredients().get(rowIndex).setIncluded((Boolean) aValue);
                fireTableDataChanged();
                break;
            case 1: // Quantity
                recipe.getIngredients().get(rowIndex).setQuantity(
                        MesuredIngredientAdaptor.toDecimal(aValue.toString()));
                fireTableDataChanged();
                break;
            case 2: //Unit
                double w1 = recipe.getIngredients().get(rowIndex).getWeight();
                recipe.getIngredients().get(rowIndex).setUnit(
                        Unit.valueOf(aValue.toString()));
                double w2 = recipe.getIngredients().get(rowIndex).getWeight();
                recipe.getIngredients().get(rowIndex).setQuantity(
                        recipe.getIngredients().get(rowIndex).getQuantity() * w1 / w2);
                fireTableDataChanged();
                break;
            case 3: // Percentage
                recipe.getIngredients().get(rowIndex).setPercentage(
                        Double.parseDouble(aValue.toString())/ 100);
                //fireTableRowsUpdated(rowIndex, rowIndex);
                fireTableDataChanged();
                break;
            
            case 5: //Ingredient
                recipe.getIngredients().get(rowIndex).setIngredient(
                        stringToIngredient(aValue.toString()));
                //Change Unit to default unit.
                recipe.getIngredients().get(rowIndex).setUnit(
                        stringToIngredient(aValue.toString()).getUnit());
                if (recipe.getIngredients().get(rowIndex).getQuantity() == 0)
                    recipe.getIngredients().get(rowIndex).setQuantity(1.0);
                fireTableDataChanged();
                break;  
        }
    }
    
    

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        //System.out.println(recipe.getMeasurementType());
        switch(columnIndex) {
            case 0: //Optional
                return true;
            case 1: //Quantity
                if(recipe.getMeasurementType().equals(MeasurementType.QUANTITY))
                    return true;
                break;
            case 2: //Unit
                return recipe.getIngredients().get(rowIndex).getIngredient().
                        getAlternativeUnit() == null;
            case 3: // %
                if(recipe.getMeasurementType().equals(MeasurementType.PERCENTAGE)) {
                    return true;
                }
                break;
            case 5: //Ingredient
                return true;
        }
        return false;
        
    }
    
    public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
    }
    
    private Ingredient stringToIngredient(String ingd) {
        for (int i = 0; i < ingredients.size(); i++)
            if(ingd.equals(ingredients.get(i).getName()))
                return ingredients.get(i);
        return null;
    }

    public void propertyChange(PropertyChangeEvent evt) {
        if(evt.getPropertyName().equals(Recipe.PROP_SERVINGS)) {
            fireTableDataChanged();
        }
    }
    
    public void updateAll() {
        fireTableDataChanged();
    }
    
    
}
